home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1994 October / Macformat17.cdr / Shareware City / Developers / shutdown-fx-201-c / sfx ƒ / sfx control app ƒ / sfx code ƒ / debinhex dispatch.c next >
Text File  |  1994-07-11  |  7KB  |  274 lines

  1. /**********************************************************************\
  2.  
  3. File:        debinhex dispatch.c
  4.  
  5. Purpose:    This module handles the main dispatch routine for
  6.             deBinHexing.
  7.  
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2 of the License, or
  11. (at your option) any later version.
  12.  
  13. This program is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. GNU General Public License for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with this program in a file named "GNU General Public License".
  20. If not, write to the Free Software Foundation, 675 Mass Ave,
  21. Cambridge, MA 02139, USA.
  22.  
  23. \**********************************************************************/
  24.  
  25. #include "debinhex dispatch.h"
  26. #include "debinhex.h"
  27. #include "file management.h"
  28. #include "error.h"
  29. #include "progress.h"
  30. #include "util.h"
  31. #include "file interface.h"
  32.  
  33. typedef struct
  34. {
  35.     long        fileType;
  36.     long        fileCreator;
  37.     short        finderFlags;
  38.     long        dataLen;
  39.     long        resLen;
  40.     short        checksum;
  41. } BinHexHeaderStruct;
  42.  
  43. #define MAX_HEADER_OFFSET    10240
  44.  
  45. enum ErrorTypes DeBinHexDispatch(void)
  46. {
  47.     enum ErrorTypes        resultCode;
  48.     
  49.     outputFS=inputFS;
  50.     OpenInputFile();
  51.     InitDeBinHex();
  52.     resultCode=GetBinHexHeader();
  53.     if (resultCode!=allsWell)
  54.         return resultCode;
  55.     resultCode=CreateTempFile();
  56.     if (resultCode!=allsWell)
  57.         return resultCode;
  58.     SetupTempFile();
  59.     resultCode=BinHexDecode();
  60.     EndDeBinHex();
  61.     FinalizeFiles(resultCode==allsWell);
  62.     return resultCode;
  63. }
  64.  
  65. enum ErrorTypes GetBinHexHeader(void)
  66. {
  67.     unsigned char        namelen;
  68.     unsigned char        Buffy[100];
  69.     unsigned char        *theText;
  70.     enum ErrorTypes        resultCode;
  71.     BinHexHeaderStruct    header;
  72.     unsigned long        realLen;
  73.     unsigned char        oneChar;
  74.     short                iter;
  75.     Boolean                notDoneYet;
  76.     short                offset;
  77.     
  78.     theText=(unsigned char*)NewPtrClear(MAX_HEADER_OFFSET);
  79.     Mymemcpy((Ptr)Buffy, (Ptr)((long)(*GetString(BINHEX_HEADER_STRING))+1), 47);
  80.     iter=1;
  81.     notDoneYet=TRUE;
  82.     resultCode=ReadInputFile(inputRefNum, (Ptr)theText, 10240L, &realLen);
  83.     if (resultCode!=allsWell)
  84.         return resultCode;
  85.     offset=0;
  86.     do
  87.     {
  88.         oneChar=*((unsigned char*)((long)theText+(offset++)));
  89.         if (offset==MAX_HEADER_OFFSET)
  90.         {
  91.             DisposePtr((Ptr)theText);
  92.             return kBinHexErr;
  93.         }
  94.         if (oneChar==Buffy[iter])
  95.         {
  96.             iter++;
  97.             notDoneYet=(iter<41);
  98.         }
  99.         else
  100.         {
  101.             iter=0;
  102.             if (oneChar==Buffy[iter])
  103.                 iter++;
  104.         }
  105.     }
  106.     while (notDoneYet);
  107.     
  108.     notDoneYet=TRUE;
  109.     do
  110.     {
  111.         oneChar=*((unsigned char*)((long)theText+(offset++)));
  112.         if (offset==MAX_HEADER_OFFSET)
  113.         {
  114.             DisposePtr((Ptr)theText);
  115.             return kBinHexErr;
  116.         }
  117.         if ((oneChar==0x0a) || (oneChar==0x0d))
  118.             notDoneYet=FALSE;
  119.     }
  120.     while (notDoneYet);
  121.     
  122.     oneChar=*((unsigned char*)((long)theText+(offset++)));
  123.     if (offset==MAX_HEADER_OFFSET)
  124.     {
  125.         DisposePtr((Ptr)theText);
  126.         return kBinHexErr;
  127.     }
  128.     notDoneYet=((oneChar==0x09) || (oneChar==0x0a) || (oneChar==0x0d) ||
  129.         (oneChar==0x20));
  130.  
  131.     while (notDoneYet)
  132.     {
  133.         oneChar=*((unsigned char*)((long)theText+(offset++)));
  134.         if (offset==MAX_HEADER_OFFSET)
  135.         {
  136.             DisposePtr((Ptr)theText);
  137.             return kBinHexErr;
  138.         }
  139.         notDoneYet=((oneChar==0x09) || (oneChar==0x0a) || (oneChar==0x0d) ||
  140.             (oneChar==0x20));
  141.     }
  142.     
  143.     DisposePtr((Ptr)theText);
  144.     
  145.     if (oneChar!=':')
  146.         return kBinHexErr;
  147.     
  148.     SetFPos(inputRefNum, 1, offset);
  149.     resultCode=GetNBytes(inputRefNum, (Ptr)Buffy, 1);
  150.     if (resultCode!=allsWell)
  151.         return resultCode;
  152.     namelen=Buffy[0];
  153.     resultCode=GetNBytes(inputRefNum, (Ptr)((long)Buffy+1), namelen+21);
  154.     if (resultCode!=allsWell)
  155.         return resultCode;
  156.     Mymemcpy((Ptr)(&header), (Ptr)((long)Buffy+namelen+2), sizeof(header));
  157.     *((char*)((long)Buffy+namelen+20))=0x00;
  158.     *((char*)((long)Buffy+namelen+21))=0x00;
  159.     if (header.checksum!=BinHexChecksum((Ptr)Buffy, namelen+22, TRUE))
  160.         return kBinHexErr;
  161.     Mymemcpy((Ptr)outputFS.name, (Ptr)Buffy, namelen+1);
  162.     outputDFeof=header.dataLen;
  163.     outputRFeof=header.resLen;
  164.     theFileType=header.fileType;
  165.     theFileCreator=header.fileCreator;
  166.     theFileFlags=header.finderFlags;
  167.     
  168.     return allsWell;
  169. }
  170.  
  171. enum ErrorTypes BinHexDecode(void)
  172. {
  173.     Ptr                outputBuffer;
  174.     enum ErrorTypes    resultCode;
  175.     unsigned long    bufferLen;
  176.     Boolean            notDoneYet;
  177.     unsigned long    curPos, len, forkPos;
  178.     Boolean            useDF;
  179.     DialogPtr        theDlog;
  180.     unsigned short    oldcheck;
  181.     unsigned char    temp1,temp2;
  182.     
  183.     theDlog=OpenProgressDialog(outputDFeof+outputRFeof+4, "\pDeBinHex");
  184.     if (theDlog==0L)
  185.         return kNoMemory;
  186.     SetProgressText("\pConverting ",inputFS.name, "\p from BinHex format...","\p");
  187.     DealWithOtherPeople();
  188.     bufferLen=BINHEX_BUFFER_LENGTH;
  189.     outputBuffer=NewPtr(bufferLen);
  190.     if (outputBuffer==0L)
  191.         return kNoMemory;
  192.     curPos=0L;
  193.     forkPos=0L;
  194.     notDoneYet=TRUE;
  195.     useDF=TRUE;
  196.     resultCode=allsWell;
  197.     BinHexChecksum(outputBuffer, 0, TRUE);
  198.     
  199.     do
  200.     {
  201.         if (useDF)
  202.             len=(outputDFeof+2-forkPos<bufferLen) ?
  203.                 outputDFeof+2-forkPos : bufferLen;
  204.         else
  205.             len=(outputRFeof+2-forkPos<bufferLen) ?
  206.                 outputRFeof+2-forkPos : bufferLen;
  207.         
  208.         resultCode=GetNBytes(inputRefNum, outputBuffer, len);
  209.  
  210.         if (resultCode==allsWell)
  211.         {
  212.             if (len!=bufferLen)
  213.             {
  214.                 if (useDF)
  215.                 {
  216.                     temp1=*((unsigned char*)((long)outputBuffer+outputDFeof-forkPos));
  217.                     temp2=*((unsigned char*)((long)outputBuffer+outputDFeof-forkPos+1));
  218.                     oldcheck=0;
  219.                     oldcheck+=temp1;
  220.                     oldcheck<<=8;
  221.                     oldcheck+=temp2;
  222.                     *((unsigned char*)((long)outputBuffer+outputDFeof-forkPos))=0x00;
  223.                     *((unsigned char*)((long)outputBuffer+outputDFeof-forkPos+1))=0x00;
  224.                     if (oldcheck!=BinHexChecksum(outputBuffer, len, FALSE))
  225.                         resultCode=kBinHexErr;
  226.                     if ((resultCode==allsWell) && (len>2))
  227.                         resultCode=WriteTempFile(outputDFRefNum, outputBuffer, len-2);
  228.                     useDF=FALSE;
  229.                     forkPos=0L;
  230.                     BinHexChecksum(outputBuffer, 0, TRUE);
  231.                 }
  232.                 else
  233.                 {
  234.                     temp1=*((unsigned char*)((long)outputBuffer+outputRFeof-forkPos));
  235.                     temp2=*((unsigned char*)((long)outputBuffer+outputRFeof-forkPos+1));
  236.                     oldcheck=0;
  237.                     oldcheck+=temp1;
  238.                     oldcheck<<=8;
  239.                     oldcheck+=temp2;
  240.                     *((unsigned char*)((long)outputBuffer+outputRFeof-forkPos))=0x00;
  241.                     *((unsigned char*)((long)outputBuffer+outputRFeof-forkPos+1))=0x00;
  242.                     if (oldcheck!=BinHexChecksum(outputBuffer, len, FALSE))
  243.                         resultCode=kBinHexErr;
  244.                     if ((resultCode==allsWell) && (len>2))
  245.                         resultCode=WriteTempFile(outputRFRefNum, outputBuffer, len-2);
  246.                     notDoneYet=FALSE;
  247.                 }
  248.             }
  249.             else
  250.             {
  251.                 forkPos+=len;
  252.                 BinHexChecksum(outputBuffer, len, FALSE);
  253.                 if (useDF)
  254.                     resultCode=WriteTempFile(outputDFRefNum, outputBuffer, len);
  255.                 else
  256.                     resultCode=WriteTempFile(outputRFRefNum, outputBuffer, len);
  257.             }
  258.             if (resultCode==allsWell)
  259.             {
  260.                 curPos+=len;
  261.                 UpdateProgressDialog(curPos);
  262.                 if (!DealWithOtherPeople())
  263.                     resultCode=userCancelErr;
  264.             }
  265.         }
  266.     }
  267.     while ((notDoneYet) && (resultCode==allsWell));
  268.  
  269.     DisposePtr(outputBuffer);
  270.     DismissProgressDialog();
  271.     
  272.     return resultCode;
  273. }
  274.